//
//  WATFSpeedManager.swift
//  WiFiFaster
//
//  Created by one on 2023/12/29.
//

import UIKit
import Alamofire
import NetworkExtension
let watf_saveDownloadFile = "watf_saveDownloadFile"
extension WATFManager {
    func watf_stopDownloadTest() {
        if watf_downloadRequest == nil {
            return
            
        }
        watf_downloadRequest?.cancel()
        watf_downloadRequest = nil
    }
    func watf_stopUploadTest() {
        if watf_uploadRequest == nil {
            return
            
        }
        watf_uploadRequest?.cancel()
        watf_uploadRequest = nil
    }
    func watf_deleteLocalSaveVideo() {
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let fileURL = documentsURL.appendingPathComponent("\(watf_saveDownloadFile).mp4")
        try? FileManager.default.removeItem(at: fileURL)
    }
    
    func watf_startSpeedScan() {
        watf_uploadValue = 0
        watf_downloadValue = 0
        WATFNetSpeedCom.watf_speed().watf_startListening()
        WATFNetSpeedCom.watf_speed().delegate = self
        watf_deleteLocalSaveVideo()
        watf_stopDownloadRequest = false
        watf_stopUploadRequest = false
        watf_startDownloadTestRequest()
    }
    func watf_stopSpeedScan() {
        watf_deleteLocalSaveVideo()
        watf_stopDownloadTest()
        watf_stopUploadTest()
        watf_stopUploadTestTimer()
        watf_stopDownloadTimerTest()
        watf_stopPingTest()
        self.watf_stopDownloadRequest = true
        self.watf_stopUploadRequest = true
        watf_delegate = nil
        watf_uploadValue = 0
        watf_downloadValue = 0
        WATFNetSpeedCom.watf_speed().watf_stopListening()
        WATFNetSpeedCom.watf_speed().delegate = nil
        watf_speedType = -1
    }
    private func watf_startDownloadTestRequest() {
        watf_speedType = 0
        watf_downAddDataTest()
        watf_startDownloadTimerTest()
        
    }
    private func watf_downAddDataTest() {
        if watf_stopDownloadRequest {
            return
        }
        let destination: DownloadRequest.Destination = { _, _ in
            let watf_documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            let watf_fileURL = watf_documentsURL.appendingPathComponent("\(watf_saveDownloadFile).mp4")
            
            return (watf_fileURL, [.removePreviousFile, .createIntermediateDirectories])
        }
        watf_downloadRequest = AF.download("https://www.apple.com/105/media/cn/ipad/2018/08716702_0a2f_4b2c_9fdd_e08394ae72f1/films/browse-files/ipad-browse-files-tpl-cn-20180404_1280x720h.mp4", to: destination).responseString(completionHandler: { watf_res in
            if !self.watf_stopDownloadRequest {
                self.watf_downloadRequest?.cancel()
                self.watf_downloadRequest = nil
                if self.watf_downAddNumber > 8 {
                    self.watf_stopDownloadRequest = true
                    return
                }
                self.watf_downAddDataTest()
            }
            
        })
        
    }
    
    fileprivate func watf_startDownloadTimerTest() {
        watf_stopDownloadTimerTest()
        watf_downloadName = WATFTimerCom.watf_timeTask(self, selector: #selector(watf_timerDownloadAdd), start: 0, interval: 1, repeats: true, async: false, name: watf_downloadName)
    }
    
    fileprivate func watf_stopDownloadTimerTest() {
        WATFTimerCom.watf_cancelTask(watf_downloadName)
        watf_downloadName = "watf_downloadName"
        watf_downAddNumber = 0
    }
    
    @objc fileprivate func watf_timerDownloadAdd() {
        watf_downAddNumber = watf_downAddNumber + 1
       
        if watf_downAddNumber > 8 {
            self.watf_deleteLocalSaveVideo()
            self.watf_stopDownloadTimerTest()
            watf_delegate?.watf_downloadFinish?(watf_value: WATFCommon.watf_changeSizeValue(size: watf_downloadValue/8))
            watf_stopDownloadTest()
            watf_startUploadTestRequest()
        }
    }
}

extension WATFManager {
    fileprivate func watf_startUploadTestRequest() {
        watf_speedType = 1
        watf_deleteLocalSaveVideo()
        autoreleasepool {
            var watf_videoData = Data(repeating: 0x42, count: 48510692)
            let watf_videoData2 = watf_videoData
            watf_videoData.append(watf_videoData2)
            watf_sumUpVideoData(watf_data: watf_videoData)
            watf_startUpTimerTest()
        }
        
    }
    fileprivate func watf_sumUpVideoData(watf_data: Data, watf_isAdd: Bool = true) {
        if watf_stopUploadRequest {
            return
        }
        var watf_videoData = watf_data
        if watf_isAdd {
            watf_videoData.append(watf_data)
        }
        
        watf_uploadRequest = AF.upload(multipartFormData: { multipartFormData in
            multipartFormData.append(watf_videoData, withName: "file")
        }, to: "https://httpbin.org/post")
        
        watf_uploadRequest?.responseString(completionHandler: { watf_res in
            if !self.watf_stopUploadRequest {
                self.watf_uploadRequest?.cancel()
                self.watf_uploadRequest = nil
                if self.watf_uploadAddNumber > 8 {
                    self.watf_stopUploadRequest = true
                    return
                }
                
                self.watf_sumUpVideoData(watf_data: watf_videoData, watf_isAdd: false)
            }
            
        })
        
        
    }
    fileprivate func watf_startUpTimerTest() {
        watf_stopUploadTestTimer()
        watf_uploadName = WATFTimerCom.watf_timeTask(self, selector: #selector(watf_timerUploadAdd), start: 0, interval: 1, repeats: true, async: false, name: watf_uploadName)
    }
    
    fileprivate func watf_stopUploadTestTimer() {
        WATFTimerCom.watf_cancelTask(watf_uploadName)
        watf_uploadName = "watf_uploadName"
        watf_uploadAddNumber = 0
    }
    
    @objc fileprivate func watf_timerUploadAdd() {
        watf_uploadAddNumber = watf_uploadAddNumber + 1
       
        if watf_uploadAddNumber > 8 {
            watf_stopUploadTestTimer()
            self.watf_delegate?.watf_upLoadFinish?(watf_value: WATFCommon.watf_changeSizeValue(size: watf_uploadValue/8))
            watf_stopUploadTest()
            self.watf_startSpeedScanPing()
        }
    }
}

extension WATFManager {
    func watf_startSpeedScanPing() {
        watf_speedType = 2
        var watf_values = [Int]()
        watf_pingServe = WATFPingSer.startPingAddress("www.apple.com", callbackHandler: { watf_item, watf_items in
            if watf_item.status == .error ||  watf_item.status == .didTimeout {
                let watf_allCount:Double = Double(watf_values.count)
                watf_values = watf_values.filter({ watf_va in
                    return watf_va != 0
                })
                self.watf_pingServe = nil
                let watf_value = watf_values.reduce(0)  {
                    $0 + $1
                }
                if watf_value == 0 || watf_values.count == 0 {
                    self.watf_delegate?.watf_pingFinish?(watf_ping: "0ms", watf_jitter: "0ms", watf_loss: "0%")
                    return
                }
                let watf_lossC:Double = watf_allCount-Double(watf_values.count)
                let watf_loss = Int((watf_lossC/watf_allCount)*100)
                let watf_jitter = (watf_values.max() ?? 0) - (watf_values.min() ?? 0)
                self.watf_delegate?.watf_pingFinish?(watf_ping: "\(watf_value/watf_values.count)ms", watf_jitter: "\(watf_jitter)ms", watf_loss: "\(watf_loss)%")
                return
            }
            if watf_item.status != .finished {
                
                watf_values.append(Int(watf_item.timeMilliseconds))
                if Int(watf_item.timeMilliseconds) != 0 {
                    self.watf_delegate?.watf_pingProcess?(watf_ping: "\(Int(watf_item.timeMilliseconds))ms")
                }
                
            }else {
                let watf_allCount:Double = Double(watf_values.count)
                watf_values = watf_values.filter({ watf_va in
                    return watf_va != 0
                })
                self.watf_pingServe = nil
                let watf_value = watf_values.reduce(0)  {
                    $0 + $1
                }
                if watf_value == 0 || watf_values.count == 0 {
                    self.watf_delegate?.watf_pingFinish?(watf_ping: "0ms", watf_jitter: "0ms", watf_loss: "0%")
                    return
                }
                let watf_lossC:Double = watf_allCount-Double(watf_values.count)
                let watf_loss = Int((watf_lossC/watf_allCount)*100)
                let watf_jitter = (watf_values.max() ?? 0) - (watf_values.min() ?? 0)
                self.watf_delegate?.watf_pingFinish?(watf_ping: "\(watf_value/watf_values.count)ms", watf_jitter: "\(watf_jitter)ms", watf_loss: "\(watf_loss)%")
            }
        })
        watf_pingServe?.maximumPingTimes = 10
    }
    func watf_stopPingTest() {
        watf_pingServe?.watf_stop()
        watf_pingServe = nil
    }
}

extension WATFManager: WATFNetSpeedComDelegate {
    func watf_updateNetSendValue(_ watf_value: UInt64) {
        if watf_speedType != 1 {
            return
        }
        watf_uploadValue += Double(watf_value)
        watf_delegate?.watf_uploadProcess?(watf_value: WATFCommon.watf_changeSizeValue(size:  Double(watf_value)))
        print(watf_uploadValue, "上传")
    }
    func watf_updateNetReceiveValue(_ watf_value: UInt64) {
        if watf_speedType != 0 {
            return
        }
        watf_downloadValue += Double(watf_value)
        watf_delegate?.watf_downloadProcess?(watf_value: WATFCommon.watf_changeSizeValue(size:  Double(watf_value)))
        print(watf_downloadValue, "下载")
    }
}
